package pool

import (
	"fmt"
	"sync"
)

type Task struct {
	f func() error
}

func (that *Task) Execute() error {
	return that.f()
}

func NewTask(f func() error) *Task {
	task := Task{f: f}
	return &task
}

type Pool struct {
	EntryChan chan *Task
	InnerChan chan *Task
	MaxNum    int
	taskList  []*Task
	wg        sync.WaitGroup
}

func NewPoll(maxNum int) *Pool {
	pool := Pool{
		EntryChan: make(chan *Task),
		InnerChan: make(chan *Task),
		MaxNum:    maxNum,
		taskList:  make([]*Task, 0),
	}

	pool.wg.Add(maxNum + 1)

	return &pool
}

func (that *Pool) work(i int) {
	for task := range that.InnerChan {
		_ = task.Execute()
		fmt.Println("work", i, "正在执行工作")
	}
	that.wg.Done()
}

func (that *Pool) Run() {
	go func() {
		for i := 0; i < that.MaxNum; i++ {
			go that.work(i)
		}

		for task := range that.EntryChan {
			that.InnerChan <- task
		}
		close(that.InnerChan)

		that.wg.Done()
	}()

	for _, task := range that.taskList {
		that.EntryChan <- task
	}
	close(that.EntryChan)
}

func (that *Pool) AddTask(task *Task) {
	that.taskList = append(that.taskList, task)
}
